package mob.dev.blpr;


// modified for blpr_todo_list application from Tasks Sample

/*
 * Copyright (c) 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

import com.google.api.client.extensions.android2.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessProtectedResource;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpRequest;
import com.google.api.client.http.json.JsonHttpRequestInitializer;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.tasks.Tasks;
import com.google.api.services.tasks.TasksRequest;
import com.google.api.services.tasks.model.Task;
import com.google.api.client.util.DateTime;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
///import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
//import android.widget.ListView;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
//import java.text.ParseException;
//import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
//import java.util.Date;

/**
 * Sample for Tasks API on Android. It shows how to authenticate using OAuth 2.0, and get the list
 * of tasks.
 * <p>
 * To enable logging of HTTP requests/responses, change {@link #LOGGING_LEVEL} to
 * {@link Level#CONFIG} or {@link Level#ALL} and run this command:
 * </p>
 * 
 * <pre>adb shell setprop log.tag.HttpTransport DEBUG * </pre>
 * 
 * @author Johan Euphrosine (based on Yaniv Inbar Buzz sample)
 */
public class Blpr_todo_listActivity extends ListActivity {

  /** Logging level for HTTP requests/responses. */
  private static final Level LOGGING_LEVEL = Level.OFF;

  private static final String TAG = "blpr_todo_list";

  // This must be the exact string, and is a special for alias OAuth 2 scope
  // "https://www.googleapis.com/auth/tasks"
  private static final String AUTH_TOKEN_TYPE = "Manage your tasks";

  private static final String PREF = "MyPrefs";
  private static final int DIALOG_ACCOUNTS = 0;
  private static final int ITEM_CLICKED = 1;
  private static final int MENU_ACCOUNTS = 0;
  public static final int REQUEST_AUTHENTICATE = 0;
  
  //Brian Lawless added in order to remove need for clientCredentials and reduce complexity
  //This is the API key for "Simple API access" for our application
  private static final String KEY = "AIzaSyDKSAppmF0ul762fkRfvpTFNp2hdzy8wio";
  //a new menu id to add a new task
  private static final int ADD_TASK = 1;
  private static final int SHOW_ALL = 2;
  
  private static final int NEW_TASK = 1;
  private static final int EDIT_TASK = 2;
  
  private static final int MENU_COMPLETE = 0;
  private static final int MENU_EDIT = 1;
  
  private static final int CANCEL = 0;
  private static final int SAVE = 1;
  
  private boolean showAll;
  
  private List<Task> tasks;
  private List<String> taskTitles; 
  
 
  private final HttpTransport transport = AndroidHttp.newCompatibleTransport();
  
  
  private Tasks service;
  GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(null);

  public String authToken;
  GoogleAccountManager accountManager;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //initially only show uncompleted
    showAll = false;
    
    //TODO(lawlesbd) add multithreaded capability so strictMode work around is not needed
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
   
    service =
        Tasks.builder(transport, new JacksonFactory()).setApplicationName("blpr_todo_list")
            .setHttpRequestInitializer(accessProtectedResource)
            .setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {

              @Override
			public void initialize(JsonHttpRequest request) throws IOException {
                TasksRequest tasksRequest = (TasksRequest) request;
                tasksRequest.setKey(KEY);
              }
            }).build();
    
    accountManager = new GoogleAccountManager(this);
    Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
    
    gotAccount(false);
    
    
  }
  
  @Override
  protected Dialog onCreateDialog(int id) {
	  AlertDialog.Builder builder = new AlertDialog.Builder(this);
    switch (id) {
      case DIALOG_ACCOUNTS:
        builder.setTitle("Select a Google account");
        final Account[] accounts = accountManager.getAccounts();
        final int size = accounts.length;
        String[] names = new String[size];
        for (int i = 0; i < size; i++) {
          names[i] = accounts[i].name;
        }
        builder.setItems(names, new DialogInterface.OnClickListener() {
          @Override
		public void onClick(DialogInterface dialog, int which) {
            gotAccount(accounts[which]);
          }
        });
        return builder.create();
     
    }
    return null;
  }

  void gotAccount(boolean tokenExpired) {
    SharedPreferences settings = getSharedPreferences(PREF, 0);
    String accountName = settings.getString("accountName", null);
    Account account = accountManager.getAccountByName(accountName);
    if (account != null) {
      if (tokenExpired) {
        accountManager.invalidateAuthToken(accessProtectedResource.getAccessToken());
        accessProtectedResource.setAccessToken(null);
      }
      gotAccount(account);
      return;
    }
    showDialog(DIALOG_ACCOUNTS);
  }

  void gotAccount(final Account account) {
    SharedPreferences settings = getSharedPreferences(PREF, 0);
    SharedPreferences.Editor editor = settings.edit();
    editor.putString("accountName", account.name);
    editor.commit();
    accountManager.manager.getAuthToken(account, AUTH_TOKEN_TYPE, true,
        new AccountManagerCallback<Bundle>() {

          @Override
		public void run(AccountManagerFuture<Bundle> future) {
            try {
              Bundle bundle = future.getResult();
              if (bundle.containsKey(AccountManager.KEY_INTENT)) {
                Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
                intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivityForResult(intent, REQUEST_AUTHENTICATE);
              } else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) {
                accessProtectedResource.setAccessToken(bundle
                    .getString(AccountManager.KEY_AUTHTOKEN));
                onAuthToken();
              }
            } catch (Exception e) {
              handleException(e);
            }
          }
        }, null);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
      case REQUEST_AUTHENTICATE:
        if (resultCode == RESULT_OK) {
          gotAccount(false);
        } else {
          showDialog(DIALOG_ACCOUNTS);
        }
        break;
      //added for blpr_todo_list app  
      case NEW_TASK:
    	  if(resultCode == SAVE){
	    	  
	    	  Task updatedTask = new Task();
	    	  
	    	  updatedTask.setTitle(data.getExtras().getString("Title"));
	    	  updatedTask.setDue(DateTime.parseRfc3339(data.getExtras().getString("DueDate")));
	    	  updatedTask.setNotes(data.getExtras().getString("Notes"));
		  	  try{
				  Task result = service.tasks().insert("@default", updatedTask).execute();
				  //if (result != null)
					  //onAuthToken();
			  } catch (IOException e){
				  handleException(e);
			  }  
    	  }
    	  onAuthToken();
    	  break;
      case EDIT_TASK:
    	  if(resultCode == SAVE){
	    	  String taskId = data.getExtras().getString("Id");
	    	  Task updatedTask = null;
	    	  for(Task task: tasks){
	    		  if(task.getId().equals(taskId)){
	    		  	updatedTask = task;
	    		  	break;
	    		  }
	    	  }
	    	  updatedTask.setTitle(data.getExtras().getString("Title"));
	    	  updatedTask.setDue(DateTime.parseRfc3339(data.getExtras().getString("DueDate")));
	  		  updatedTask.setNotes(data.getExtras().getString("Notes"));
	  		try{
				  Task result = service.tasks().update("@default", updatedTask.getId(), updatedTask).execute();
				  //if (result != null)
					  //onAuthToken();
			  } catch (IOException e){
				  handleException(e);
			  }
	  		  
    	  }
    	  onAuthToken();
    	  break;
    	default:
    	  break;
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, MENU_ACCOUNTS, 0, "Switch Account");
    menu.add(0, ADD_TASK, 0, "New Task");
    menu.add(0, SHOW_ALL, 0, "Toggle Completed");
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case MENU_ACCOUNTS:
        showDialog(DIALOG_ACCOUNTS);
        return true;
      //add task added for blpr_todo_list  
      case ADD_TASK:
    	newTask();
    	return true;
      case SHOW_ALL:
    	  showAll = !showAll;
    	  onAuthToken();
    	  return true;
    }
    return false;
  }
  
  
  private void newTask() {
	//this method added for blpr_todo_list  
	Intent addTaskIntent = new Intent(this, newTaskActivity.class );
	startActivityForResult(addTaskIntent, NEW_TASK);
  }

  void handleException(Exception e) {
	e.printStackTrace();
	if (e instanceof HttpResponseException) {
	  HttpResponse response = ((HttpResponseException) e).getResponse();
	  int statusCode = response.getStatusCode();
	  try {
	    response.ignore();
	  } catch (IOException e1) {
	    e1.printStackTrace();
	  }
	  // TODO(yanivi): should only try this once to avoid infinite loop
	  if (statusCode == 401) {
	    gotAccount(true);
	    return;
	  }
	}
	Log.e(TAG, e.getMessage(), e);
  }

  void onAuthToken() {
    try {
      taskTitles = new ArrayList<String>();
      tasks = service.tasks().list("@default").execute().getItems();
      if (tasks != null) {
    	SharedPreferences prefs = getSharedPreferences("tasks_list", Context.MODE_PRIVATE);
    	SharedPreferences.Editor editor = prefs.edit();
    	editor.clear();
    	Integer i = 0;
        for (Task task : tasks) {
        	
        	if(task.getCompleted() == null){
        		taskTitles.add(task.getTitle());
        		editor.putString(i.toString(), task.getTitle());
        		i++;
        	}
        	else if(showAll){
        		editor.putString(i.toString(), task.getTitle());
        		i++;
        		taskTitles.add(task.getTitle() + " - COMPLETE!");
        	}
        }
        editor.commit();
      } else {
        taskTitles.add("No tasks.");
      }
      
      
     
    } catch (IOException e) {
      handleException(e);
    }
    setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_activated_1, taskTitles));
    
    registerForContextMenu(getListView());
      
  }
 
  	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
		menu.add(Menu.NONE, MENU_COMPLETE, Menu.NONE, "Mark Task Complete");
		menu.add(Menu.NONE, MENU_EDIT, Menu.NONE, "Edit Task");
	}

  	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info=
			(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
		//ArrayAdapter<String> adapter=(ArrayAdapter<String>)getListAdapter();

		switch (item.getItemId()) {
			case MENU_COMPLETE:
				
				 for(Task task : tasks){
					  if(task.getTitle().equals(taskTitles.get(info.position))){
						  try{
							  task.setStatus("completed");
							  Task result = service.tasks().update("@default", task.getId(), task).execute();
							  if (result != null)
								  onAuthToken();
						  } catch (IOException e){
							  handleException(e);
						  }
						  break;
					  }
					  
				}
				
				return(true);
		
			case MENU_EDIT:
				
				for(Task task : tasks){
					  if(task.getTitle().equals(taskTitles.get(info.position))){
						  editTask(task);
						  break;
					  }
					  
				}
				
				return(true);
		}
		return true;
  	}
  	
  	private void editTask(Task task) {
  		//this method added for blpr_todo_list  
  		Intent editTaskIntent = new Intent(this, newTaskActivity.class );
  		editTaskIntent.putExtra("Id", task.getId());
  		editTaskIntent.putExtra("Title", task.getTitle());
  		editTaskIntent.putExtra("DueDate", task.getDue() != null?task.getDue().toStringRfc3339():"");
  		System.out.println(task.getDue().toStringRfc3339());
  		editTaskIntent.putExtra("Notes", task.getNotes());
  		startActivityForResult(editTaskIntent, EDIT_TASK);
  	  }
  	

}
